<template>
    <div class="image-upload-component">
        <div class="form-header">
            <label class="form-label" v-if="label">{{ label }}</label>
            <div class="page-size-control" v-if="hasImages">
                <span>每页显示：</span>
                <select v-model="ITEMS_PER_PAGE" class="page-size-select">
                    <option value="5">5张</option>
                    <option value="10">10张</option>
                    <option value="15">15张</option>
                    <option value="20">20张</option>
                </select>
            </div>
        </div>
        <div 
            class="upload-area" 
            :class="{ 'disabled': disabled, 'error': error, 'loading': loading }"
            @click="triggerFileInput"
        >
            <input 
                type="file" 
                @change="handleFileChange" 
                accept="image/*"
                :multiple="multiple"
                class="file-input"
                ref="fileInput"
                style="display: none"
                :disabled="disabled || loading"
            >
            <div v-if="loading" class="loading-overlay">
                <van-loading type="spinner" color="#1E9FFF" />
                <span>上传中...</span>
            </div>
            <div v-else-if="!hasImages" class="upload-placeholder">
                <van-icon name="photograph-o" size="24" />
                <span>{{ placeholder }}</span>
            </div>
            <div v-else class="images-preview">
                <div v-for="(image, index) in paginatedImages" :key="index" class="image-item">
                    <div class="image-container">
                        <img :src="image.url" :alt="image.name">
                    </div>
                    <button class="preview-btn" @click.stop="previewImage(index)">
                        <van-icon name="search" size="16" />
                    </button>
                    <button @click.stop="removeImage(index)" class="remove-image-btn">
                        <van-icon name="cross" />
                    </button>
                </div>
                <div v-if="canAddMore" class="add-more">
                    <van-icon name="plus" size="24" />
                    <span>继续添加</span>
                </div>
            </div>
        </div>
        <div v-if="showPagination" >
            <Pagination
                :current-page="currentPage"
                :total-pages="totalPages"
                @page-change="(page) => currentPage = page"
            />
        </div>
        <div v-if="error" class="error-message">{{ errorMessage }}</div>
    </div>
</template>

<script setup>
import { ref, computed } from 'vue';
import { Icon as VanIcon, Loading as VanLoading } from 'vant';
import { showImagePreview, showToast } from 'vant';
import apiUrls from '@/config/apiUrls'; 
import request from '@/utils/request';
import Pagination from '@/Pages/compontents/Pagination.vue';

const props = defineProps({
    modelValue: {
        type: Array,
        default: () => []
    },
    label: {
        type: String,
        default: '上传图片'
    },
    placeholder: {
        type: String,
        default: '点击上传图片'
    },
    multiple: {
        type: Boolean,
        default: false
    },
    maxCount: {
        type: Number,
        default: 9
    },
    maxSize: {
        type: Number,
        default: 5 * 1024 * 1024 // 默认5MB
    },
    disabled: {
        type: Boolean,
        default: false
    },
    uploadType: {
        type: String,
        default: ''
    }
});

const emit = defineEmits(['update:modelValue', 'error']);

const fileInput = ref(null);
const error = ref(false);
const errorMessage = ref('');
const loading = ref(false);
const currentPage = ref(1);
const ITEMS_PER_PAGE = ref(5);

const hasImages = computed(() => {
    return props.modelValue.length > 0;
});

const canAddMore = computed(() => {
    return props.multiple && props.modelValue.length < props.maxCount;
});

const paginatedImages = computed(() => {
    if (props.modelValue.length <= ITEMS_PER_PAGE.value) {
        return props.modelValue;
    }
    const start = (currentPage.value - 1) * ITEMS_PER_PAGE.value;
    const end = start + ITEMS_PER_PAGE.value;
    return props.modelValue.slice(start, end);
});

const totalPages = computed(() => {
    return Math.ceil(props.modelValue.length / ITEMS_PER_PAGE.value);
});

const showPagination = computed(() => {
    return props.modelValue.length > ITEMS_PER_PAGE.value;
});

const triggerFileInput = () => {
    if (props.disabled || loading.value) return;
    
    // 检查是否已达到最大数量限制
    if (props.multiple) {
        if (props.modelValue.length >= props.maxCount) {
            error.value = true;
            errorMessage.value = `最多只能上传 ${props.maxCount} 张图片`;
            return;
        }
    } else {
        if (props.modelValue.length > 0) {
            error.value = true;
            errorMessage.value = '只能上传一张图片';
            return;
        }
    }

    if (fileInput.value) {
        fileInput.value.click();
    }
};

const validateImage = (file) => {
    if (!file.type.startsWith('image/')) {
        error.value = true;
        errorMessage.value = '请上传图片文件';
        return false;
    }

    if (file.size > props.maxSize) {
        error.value = true;
        errorMessage.value = `图片大小不能超过 ${props.maxSize / 1024 / 1024}MB`;
        return false;
    }

    return true;
};

const handleFileChange = async (event) => {
    const files = event.target.files;
    if (!files.length) return;

    error.value = false;
    errorMessage.value = '';

    // 验证所有文件
    for (const file of files) {
        if (!validateImage(file)) {
            event.target.value = '';
            return;
        }
    }

    // 检查是否超过最大数量限制
    if (props.multiple) {
        if (props.modelValue.length + files.length > props.maxCount) {
            error.value = true;
            errorMessage.value = `最多只能上传 ${props.maxCount} 张图片`;
            event.target.value = '';
            return;
        }
    } else {
        // 单张上传时，只取第一张
        if (files.length > 1) {
            error.value = true;
            errorMessage.value = '只能上传一张图片';
            event.target.value = '';
            return;
        }
    }

    const formData = new FormData();
    Array.from(files).forEach((file) => {
        formData.append('files[]', file);
    });

    try {
        loading.value = true;
        const headers = {
            'Content-Type': 'multipart/form-data'
        };
        
        if (props.uploadType) {
            headers['zhjy-type'] = props.uploadType;
        }

        console.log('上传文件信息：', {
            files: Array.from(files).map(f => ({
                name: f.name,
                size: f.size,
                type: f.type
            })),
            headers
        });

        const response = await request.post(apiUrls.zhjy.getZhjyUploadFileUrl, formData, {
            headers
        });

        console.log('上传响应：', response);
        showToast({
            message: '上传成功',
            type: 'success',
            duration: 2000
        });
        if (response.data) {
            const uploadedImages = Array.isArray(response.data) ? response.data : [response.data];
            
            if (props.multiple) {
                emit('update:modelValue', [...props.modelValue, ...uploadedImages]);

            } else {
                emit('update:modelValue', [uploadedImages[0]]);

            }
        }
    } catch (error) {
        console.error('图片上传失败:', error);
        error.value = true;
        errorMessage.value = '图片上传失败，请重试';
        emit('error', error);
    } finally {
        loading.value = false;
        event.target.value = '';
    }
};

const removeImage = (index) => {
    const newImages = [...props.modelValue];
    newImages.splice(index, 1);
    emit('update:modelValue', newImages);
};

const previewImage = (index) => {
    const images = props.modelValue.map((image) => image.url);
    showImagePreview({
        images,
        startPosition: index,
        closeable: true,
        closeIconPosition: 'top-right',
    });
};
</script>

<style scoped>
.image-upload-component {
    width: 100%;
    position: relative;
    z-index: 1;
}

.form-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
}

.form-label {
    display: block;
    margin-bottom: 8px;
    color: #333;
    font-size: 14px;
}

.upload-area {
    border: 2px dashed #ddd;
    border-radius: 6px;
    padding: 12px;
    text-align: center;
    cursor: pointer;
    transition: all 0.3s;
    position: relative;
    background: white;
    min-height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.upload-area:hover:not(.disabled) {
    border-color: #1E9FFF;
}

.upload-area.disabled {
    cursor: not-allowed;
    opacity: 0.6;
}

.upload-area.error {
    border-color: #ff4d4f;
}

.upload-area.loading {
    cursor: wait;
    border-color: #1E9FFF;
}

.upload-area.loading:hover {
    border-color: #1E9FFF;
}

.upload-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    color: #999;
    padding: 8px;
}

.upload-placeholder span {
    font-size: 14px;
}

.images-preview {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
    gap: 8px;
    padding: 4px;
    width: 100%;
    position: relative;
    z-index: 0;
}

.image-item {
    position: relative;
    aspect-ratio: 1;
    border-radius: 4px;
    overflow: hidden;
    border: 1px solid #eee;
    cursor: pointer;
    background-color: #f8f9fa;
}

.image-container {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    padding: 4px;
}

.image-item img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    transition: transform 0.3s;
}

.image-item:hover img {
    transform: scale(1.05);
}

.add-more {
    aspect-ratio: 1;
    border: 2px dashed #ddd;
    border-radius: 4px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    color: #999;
    cursor: pointer;
    transition: all 0.3s;
    padding: 4px;
}

.add-more:hover {
    border-color: #1E9FFF;
    color: #1E9FFF;
}

.add-more .van-icon {
    font-size: 20px;
}

.add-more span {
    font-size: 12px;
}

.remove-image-btn {
    position: absolute;
    top: 2px;
    right: 2px;
    background: rgba(255, 77, 79, 0.9);
    color: white;
    border: none;
    border-radius: 50%;
    width: 16px;
    height: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background-color 0.3s;
    z-index: 2;
    font-size: 12px;
}

.remove-image-btn:hover {
    background: #ff7875;
}

.preview-btn {
    position: absolute;
    top: 4px;
    left: 4px;
    background: rgba(255, 255, 255, 0.9);
    color: #1E9FFF;
    border: none;
    border-radius: 50%;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.3s;
    font-size: 12px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    z-index: 2;
}

.preview-btn:hover {
    background: #1E9FFF;
    color: white;
    transform: scale(1.1);
}

.error-message {
    color: #ff4d4f;
    font-size: 12px;
    margin-top: 4px;
}

.loading-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.9);
    gap: 8px;
    z-index: 1;
}

.loading-overlay span {
    color: #666;
    font-size: 14px;
}

.pagination {
    margin-top: 12px;
}

.page-size-control {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    color: #666;
}

.page-size-select {
    padding: 4px 8px;
    border: 1px solid #ddd;
    border-radius: 4px;
    background: white;
    cursor: pointer;
    transition: all 0.3s;
}

.page-size-select:hover {
    border-color: #1E9FFF;
}

.page-size-select:focus {
    outline: none;
    border-color: #1E9FFF;
    box-shadow: 0 0 0 2px rgba(30, 159, 255, 0.1);
}
</style> 